/* Some utility functions. e.g non-mathematical operations on matrices */

#ifndef _UTIL_H_
#define _UTIL_H_

#ifdef __cplusplus
extern "C" {
#endif

#include "matrix.h"


#define TIME_FUNC(func) { double s = read_timer(); func; double e = read_timer(); printf("Time for "#func " = %f\n", e-s); }

//#define TIME_FUNC(func) func


/* Fills with random values */
int fill_rand(matrix *A);

/* Fills with zeros */
int fill_zero(matrix *A);

/* Makes a _square_ matrix an identity matrix */
int fill_ident(matrix *A);

/* Reads a formatted matrix from the file stream F */
int read_mat(FILE *F, matrix *A);

/* Reads a matrix dump from the file stream F */
int load_mat(FILE *F, matrix *A);

/* Pretty prints matriX A to file stream F */
int print_mat(FILE *F, matrix *A);

/* Dumps the matrix to file stream F */
int dump_mat(FILE *F, matrix *A);

/* Horizontal concatenation of matrices */
int concat_mat_hor(matrix *A, matrix *B, matrix *res);

/* Vertical concatenation of matrices */
int concat_mat_ver(matrix *A, matrix *B, matrix *res);

/* gives submatrix A (start_row:end_row, start_col:end_col) */
int submatrix(matrix *A, int start_row, int end_row, int start_col, int end_col, matrix *res);

/* Compare 2 matrices, returns 1 if equal, 0 if not */
int mat_equal(matrix *A, matrix *B);

/* Copies a matrix A to another matrix B */
int copy_mat(matrix *A, matrix *B);

/* Calculates a rudimentary hash of a matrix data */
int hash_mat(matrix *A, double *hash);

double read_timer();
#ifdef __cplusplus
}
#endif

#endif /* _UTIL_H_ */
